package com.example.demo.game;

import com.example.demo.DemoApplication;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.security.SecureRandom;
import java.util.UUID;

@Data
public class Room {

    private String roomId;
    private User user1;
    private User user2;

    private ObjectMapper objectMapper = new ObjectMapper();
    //使用0表示当前位置未落子
    //使用1表示玩家1的落子位置，使用2表示玩家2的落子位置
    private int[][] board = new int[15][15];

    //@Autowired
    private OnlineUserManager onlineUserManager;

    //@Autowired
    private RoomManger roomManger;


    private UserMapper userMapper;

    private static final int MAX_ROW = 15;
    private static final int MAX_COL = 15;
    public void putChess(String reqJson) throws IOException {
        //1 记录当前落子位置
        GameRequest request = objectMapper.readValue(reqJson,GameRequest.class);
        GameResponse response = new GameResponse();

        //判断是玩家1还是玩家2落子的
        int chess = request.getUserId() == user1.getUserid() ? 1 : 2;
        int row = request.getRow();
        int col = request.getCol();
        if (board[row][col] != 0){
            System.out.println("当前位子（" + row + "," + col + ")已经有子");
        }
        board[row][col] = chess;
        //打印出棋盘信息，方便观察局势
        printBoard();
        //2 进行胜负判断
        int winner = checkWinner(row,col,chess);
        //3 给房间中所有客户端返回响应
        response.setMessage("putChess");
        response.setUserId(request.getUserId());
        response.setRow(row);
        response.setCol(col);
        response.setWinner(winner);

        //要想给用户发送数据，就需要获取到这个用户的websocketsession
        WebSocketSession session1 = onlineUserManager.getFromGameRoom(user1.getUserid());
        WebSocketSession session2 = onlineUserManager.getFromGameRoom(user2.getUserid());

        if (session1 == null){
            //玩家1下线，直接认为玩家2获胜
            response.setWinner(user2.getUserid());
            System.out.println("玩家1掉线");
        }
        if (session2 == null){
            response.setWinner(user1.getUserid());
            System.out.println("玩家2掉线");
        }

        String respJson = objectMapper.writeValueAsString(response);
        if (session1 != null){
            session1.sendMessage(new TextMessage(respJson));
        }
        if (session2 != null){
            session2.sendMessage(new TextMessage(respJson));
        }

        if (response.getWinner() != 0){
            System.out.println("游戏结束，房间销毁 roomId = " + roomId + " 获胜方:" + response.getWinner());
            //更新获胜和失败方的信息
            int winUserId = response.getWinner();
            int loseUserId = response.getWinner() == user1.getUserid() ? user2.getUserid() : user1.getUserid();
            userMapper.userWin(winUserId);
            userMapper.userLose(loseUserId);
            roomManger.remove(roomId,user1.getUserid(),user2.getUserid());
        }
    }

    private void printBoard() {
        System.out.println("打印棋盘" + "  " + roomId);
        System.out.println("==========================================================");
        for (int i = 0; i < MAX_ROW; i++) {
            for (int j = 0; j < MAX_COL; j++) {
                System.out.print(board[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println("==========================================================");
    }

    //哪个玩家获胜返回哪个玩家的id，胜负未分返回0
    private int checkWinner(int row, int col,int chess) {
        for (int c = col-4; c <= col; c++) {
            try {
                if (board[row][c] == chess
                && board[row][c+1] == chess
                && board[row][c+2] == chess
                && board[row][c+3] == chess
                && board[row][c+4] == chess){
                    return chess == 1 ? user1.getUserid() : user2.getUserid();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }

        for (int r = row-4; r <= row; r++) {
            try {
                if (board[r][col] == chess
                && board[r+1][col] == chess
                && board[r+2][col] == chess
                && board[r+3][col] == chess
                && board[r+4][col] == chess){
                    return chess == 1 ? user1.getUserid() : user2.getUserid();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }

        for (int r = row-4,c = col-4; r <= row && c <= col ; r++,c++) {
            try {
                if (board[r][c] == chess
                        && board[r+1][c+1] == chess
                        && board[r+2][c+2] == chess
                        && board[r+3][c+3] == chess
                        && board[r+4][c+4] == chess){
                    return chess == 1 ? user1.getUserid() : user2.getUserid();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }

        for (int r = row-4,c = col+4; r <= row && c >= col ; r++,c--) {
            try {
                if (board[r][c] == chess
                        && board[r+1][c-1] == chess
                        && board[r+2][c-2] == chess
                        && board[r+3][c-3] == chess
                        && board[r+4][c-4] == chess){
                    return chess == 1 ? user1.getUserid() : user2.getUserid();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }


        return 0;

    }

    //先手方的玩家id
    private int whiteUser;
    public Room(){
        //构造room时生成一个唯一字符串表示房间id
        //uuid 表示世界上唯一的身份标识（一组16进制的数字，任意次调用每次结果都不同
        roomId = UUID.randomUUID().toString();
        //通过入口类中记录的context 来手动获取到前面的roomManager和online
        onlineUserManager = DemoApplication.context.getBean(OnlineUserManager.class);
        roomManger = DemoApplication.context.getBean(RoomManger.class);
        userMapper = DemoApplication.context.getBean(UserMapper.class);
    }
}
